//配置
const fps = 60;
let rpmZone = {
	'default': [0.55, 0.8], //默认转速灯区间
};
const flashInterval = 60;//闪烁间隔ms
const wheelDegree = 540; //转动角度

//运行时数据
let carId = '-';//当前车辆ID
let AccelList = [];//油门数据
let BrakeList = [];//刹车数据
let SteerList = [];//转向数据
let GearList = [];//档位数据
let MaxGear = 6;//最大档位
let RPMList = [];//转速数据
let SpeedList = [];//车速数据
let MaxSpeed = 0;//最大车速
let lastDrawtime = 0;
let recentLaps = {}; //每一圈的第1条有效数据
let lastData = false;//最近一条有效数据
let currentLapDistance = 0;//通过第0圈直接获得的准确赛道长度
const carIdBox = document.getElementById('carId');

const stage = new Konva.Stage({
	container: 'container',
	width: width,
	height: height,
	listening: false
});

const ws = new WebSocket('ws://192.168.1.3:8080');

const baseLayer = new Konva.Layer(); //非更新层
const layer = new Konva.Layer(); //更新层
stage.add(baseLayer);
stage.add(layer);

// 绘制背景
const bg = new Konva.Rect({
	x: 0,
	y: 0,
	width: width,
	height: height,
	fill: backgroundColor
});
baseLayer.add(bg);

blocks.forEach(block => {
	const rect = new Konva.Rect({
		x: block.x,
		y: block.y,
		width: block.width,
		height: block.height,
		fill: '#1e1e1e',
		stroke: '#000000',
		strokeWidth: 5,
		cornerRadius: 10,
	});
	baseLayer.add(rect);
	const text = new Konva.Text({
		x: block.x + 10,
		y: block.y + 10,
		text: block.name,
		fontSize: 20,
		fontFamily,
		fill: '#454545'
	});
	baseLayer.add(text);
});


//通用方法
//居中文字
const centerText = options => {
	options = options || {};
	options = Object.assign({
		text: '',
		x: 0,
		y: 0,
		fontSize: 20,
		fontFamily,
		fill: '#dddddd'
	}, options);
	const text = new Konva.Text(options);
	const width = text.getTextWidth();
	const height = text.height();
	text.setX(options.x + (options.width - width) / 2);
	text.setY(options.y + (options.height - height) / 2);
	return text;
}

//格式化时间，转为 分:秒.毫秒 格式
const formatTime = time => {
	const minute = Math.floor(time / 60);
	const second = Math.floor(time % 60);
	const millisecond = Math.round((time - Math.floor(time)) * 1000);
	return `${minute < 10 ? ('0' + minute) : minute}:${('0' + second).slice(-2)}.${('000' + millisecond).slice(-3)}`;
};

//格式化时间，转换为 +/-秒.毫秒 格式，长度固定为6
const formatTime2 = time => {
	const sige = time < 0 ? '' : '+';
	let digit = 3;
	if (Math.abs(time) >= 100) {
		digit = 2;
	}
	if (Math.abs(time) >= 1000) {
		digit = 1;
	}
	if (Math.abs(time) >= 10000) {
		digit = 0;
	}
	return sige + (time.toFixed(digit));
};

//获取最高轮胎损耗
const getMaxTireWear = data => {
	return Math.max(data.TireWearFrontLeft || 0, data.TireWearFrontRight || 0, data.TireWearRearLeft || 0, data.TireWearRearRight || 0)
}
//获取赛道长度
const getLapDistance = data => {
	let lapDistance = 0;
	// if( currentLapDistance > 0 ){
	// 	lapDistance = currentLapDistance;
	// }
	// //从缓存获取
	// lapDistance = sessionStorage.getItem('LapDistance_'+data.TrackOrdinal);
	// if( lapDistance ){
	// 	currentLapDistance = lapDistance;
	// }
	//否则用出现次数最多的有效数据计算赛道长度
	let distances = {};
	for(let k in recentLaps){
		if( recentLaps[k].LastLapDistance > 0 ){
			let distance = Math.round(recentLaps[k].LastLapDistance);
			distances[ distance ] = distances[ distance ]  || 0;
			distances[ distance ]++;
		}
	}
	//获取次数最多值
	let maxCount = 0;
	let maxDistance = 0;
	for(let k in distances){
		if( distances[k] > maxCount ){
			maxCount = distances[k];
			maxDistance = k;
		}
	}
	lapDistance = maxDistance;
	return  lapDistance;
}

//计算一圈轮耗
const getLapTireWear = data => {
	let lapDistance = getLapDistance(data);
	let lastMinTireWearLapData = false;
	let tireWearPreLap = 0;
	if( lapDistance > 0 ){
		//获取最近的轮耗最小的一圈的数据
		for( let i = data.LapNumber ; i > 0 ; i-- ){ //不算第0圈
			if( !recentLaps[i] ){
				break;
			}
			if( !lastMinTireWearLapData || recentLaps[i].TireWear < lastMinTireWearLapData.TireWear ){
				lastMinTireWearLapData = recentLaps[i];
			}
			if( recentLaps[i-1] && recentLaps[i].TireWear < recentLaps[i-1].TireWear ){ //如果当前圈的胎耗小于上一圈，则认为换胎了，则退出循环
				break;
			}
		}
		let distance = data.DistanceTraveled - lastMinTireWearLapData.DistanceTraveled;
		let tireWear = data.TireWear - lastMinTireWearLapData.TireWear;
		if( distance > 0 && tireWear > 0 ){
			tireWearPreLap = tireWear / distance * lapDistance;
		}
	}
	return tireWearPreLap;
}

//计算一圈油耗
const getLapFuel = data => {
	let lapDistance = getLapDistance(data);
	let lastMaxFuelLapData = false;
	let FuelPreLap = 0;
	if( lapDistance > 0 ){
		//获取最近的剩余油量最大的一圈的数据
		for( let i = data.LapNumber ; i > 0 ; i-- ){ //不算第0圈
			if( !recentLaps[i] ){
				break;
			}
			if( !lastMaxFuelLapData || recentLaps[i].Fuel > lastMaxFuelLapData.Fuel ){
				lastMaxFuelLapData = recentLaps[i];
			}
			if( recentLaps[i-1] && recentLaps[i].Fuel > recentLaps[i-1].Fuel ){ //如果当前圈的油量大于上一圈，则认为加油了，则退出循环
				break;
			}
		}
		let distance = data.DistanceTraveled - lastMaxFuelLapData.DistanceTraveled;
		let Fuel =  lastMaxFuelLapData.Fuel - data.Fuel;
		if( distance > 0 && Fuel > 0 ){
			FuelPreLap = Fuel / distance * lapDistance;
		}
	}
	return FuelPreLap;
}

const fixNumber = (value) => {
	if (!value || isNaN(value)) {
		return '--';
	}
	if (value < 0) {
		return 0;
	}
	if (value > 99) {
		return '99+'
	}
	return value.toFixed(1);
}

const getPoints = (list, width, height , pixel = 1 ) => {
	let points = [];
	list.forEach((value, index) => {
		if( value !== null ){
			points.push(width - index * pixel);
			points.push(height - value * height);
		}else{
			points.push(undefined);
			points.push(undefined);
		}
		
	});
	return points;
}

//获取转速区间index=0:绿色区间,index=1:红色区间
const getShiftRpm = (data, index) => {
	let rpm = 0;
	if (data.CarOrdinal && rpmZone[data.CarOrdinal]) {
		rpm = rpmZone[data.CarOrdinal][index];
	}
	else if (data.EngineMaxRpm) {
		rpm = data.EngineMaxRpm * rpmZone.default[index];
	}
	return rpm;
}


ws.onmessage = function (event) {
	
	const data = JSON.parse(event.data);
	if( !data.IsRaceOn && lastData && !lastData.IsRaceOn ){
		return;
	}
	let nowTime = new Date().getTime();

	//修正当前圈数量，从0开始计数，起跑后超过发车线为第1圈
	data.LapNumber = data.LapNumber === undefined ? -1 : data.LapNumber;
	if (data.IsRaceOn && data.CurrentLap <= 0) {
		data.LapNumber = -1;
	}
	data.LapNumber = data.LapNumber + 1;
	//如果是第0圈，初始化数据
	if( data.LapNumber === 0 ){
		if( data.DistanceTraveled < -1000 ){//距离小于-1000，认为是第0圈
			currentLapDistance = Math.abs(data.DistanceTraveled);
			//写入sessionStorage
			//sessionStorage.setItem('LapDistance_'+data.TrackOrdinal, currentLapDistance);
		}
		recentLaps = {};
	}
	//更新最大轮胎损耗数据
	data.TireWear = getMaxTireWear(data);
	//在每一圈开始时，更新recentLaps数据
	if(!recentLaps[data.LapNumber] && ( data.LapNumber === 0 || data.DistanceTraveled > 0)){
		recentLaps[data.LapNumber] = data;
		if( recentLaps[data.LapNumber-1] ){//如果有上一圈数据
			recentLaps[data.LapNumber].LastLapDistance = data.DistanceTraveled - recentLaps[data.LapNumber-1].DistanceTraveled;
		}
	}

	//更新胎耗数据
	data.TireWearPreLap = getLapTireWear(data);
	//最大档位
	if( data.Gear < 10 && data.Gear > MaxGear ){
		MaxGear = data.Gear;
	}
	data.MaxGear = MaxGear;
	//最大车速
	if( data.Speed > MaxSpeed ){
		MaxSpeed = data.Speed;
	}
	data.MaxSpeed = MaxSpeed;

	//是否闪红色
	if( data.CurrentEngineRpm && data.CurrentEngineRpm >= getShiftRpm(data , 1 ) && Math.round( nowTime / flashInterval ) % 2 === 0 ){
		data.IsFlash = true;
	}else{
		data.IsFlash = false;
	}

	//更新车辆ID
	if (carId != data.CarOrdinal) {
		carId = data.CarOrdinal;
		carIdBox.innerText = carId;
	}
	//更新区块数据
	if (nowTime - lastDrawtime > 1000 / fps) {
		lastDrawtime = nowTime;
		loop(data);
	}
	lastData = data;
}

const loop = data => {
	//更新区块数据
	layer.destroyChildren();
	blocks.forEach(block => {
		if (block.contents) {
			const contents = block.contents(data, block);
			contents.forEach(content => {
				layer.add(content);
			});
		}
	});
	layer.draw();
}
const font = new FontFace('Oxanium', 'url(./fonts/oxanium.ttf)');
font.load().then(() => {
	document.fonts.add(font);
	baseLayer.draw();
	loop({})
});


//窗口缩放
function resizeWindow() {
	// 获取容器尺寸
	const container = document.querySelector('.canvas-container');
	const containerWidth = container.clientWidth;
	const containerHeight = container.clientHeight;

	// 计算缩放比例
	const scale = Math.min(
		containerWidth / width,
		containerHeight / height
	);
	document.body.style.transform = `scale(${scale})`;
}

// 初始调整
resizeWindow();
// 监听窗口变化
window.addEventListener('resize', resizeWindow);

//获取./rpmZone.ini文件内容
window.addEventListener('load', () => {
	fetch('./rpmZone.ini?' + new Date().getTime())
		.then(response => response.text())
		.then(text => {
			const lines = text.split('\n');
			let newRpmZone = {};
			lines.forEach(line => {
				line = line.trim().replace(/\s+/g, '');
				if (line && !(/^\#/.test(line))) {
					let items = line.split(":");
					if (items.length === 2) {
						items[1] = items[1].split(",");
						if (items[1].length === 2) {
							newRpmZone[items[0]] = [parseFloat(items[1][0]), parseFloat(items[1][1])];
						}
					}
				}
			});
			rpmZone = Object.assign({}, rpmZone, newRpmZone);
		})
		.catch(error => console.error(error));
});